// directives.ts
import type { Directive, DirectiveBinding } from 'vue';

/**
 * 自动聚焦指令 v-focus
 * 用法：<input v-focus />
 */
export const vFocus: Directive = {
    mounted(el: HTMLElement) {
        el.focus();
    }
};

/**
 * 权限控制指令 v-permission
 * 用法：<button v-permission="['admin', 'editor']">删除</button>
 */
export const vPermission: Directive<HTMLElement, string[]> = {
    mounted(el, binding) {
        const userRole = 'user'; // 假设从上下文获取用户角色
        if (!binding.value.includes(userRole)) {
            el.parentNode?.removeChild(el);
        }
    }
};

/**
 * 防抖点击指令 v-debounce
 * 用法：<button v-debounce="300" @click="handleClick">提交</button>
 */
export const vDebounce: Directive<HTMLElement, number> = {
    mounted(el, binding) {
        let timer: NodeJS.Timeout | null = null;
        const delay = binding.value || 300;

        el.addEventListener('click', (e: Event) => {
            if (timer) clearTimeout(timer);
            timer = setTimeout(() => {
                el.dispatchEvent(new Event('debounced-click'));
            }, delay);
        });
    }
};

/**
 * 图片懒加载指令 v-lazy
 * 用法：<img v-lazy="imageUrl" alt="图片" />
 */
export const vLazy: Directive<HTMLImageElement, string> = {
    mounted(el, binding) {
        const observer = new IntersectionObserver((entries) => {
            entries.forEach(entry => {
                if (entry.isIntersecting) {
                    el.src = binding.value;
                    observer.unobserve(el);
                }
            });
        });
        observer.observe(el);
    }
};

/**
 * 拖拽指令 v-draggable
 * 用法：<div v-draggable>可拖拽元素</div>
 */
export const vDraggable: Directive = {
    mounted(el: HTMLElement) {
        let initialX: number, initialY: number, currentX: number, currentY: number;
        let isDragging = false;

        el.style.cursor = 'move';
        el.style.position = 'relative';

        const mouseDownHandler = (e: MouseEvent) => {
            initialX = e.clientX;
            initialY = e.clientY;
            isDragging = true;
        };

        const mouseMoveHandler = (e: MouseEvent) => {
            if (!isDragging) return;
            e.preventDefault();
            currentX = e.clientX - initialX;
            currentY = e.clientY - initialY;

            el.style.transform = `translate3d(${currentX}px, ${currentY}px, 0)`;
        };

        const mouseUpHandler = () => {
            initialX = currentX = 0;
            initialY = currentY = 0;
            isDragging = false;
        };

        el.addEventListener('mousedown', mouseDownHandler);
        document.addEventListener('mousemove', mouseMoveHandler);
        document.addEventListener('mouseup', mouseUpHandler);

        (el as any).__draggableCleanup = () => {
            el.removeEventListener('mousedown', mouseDownHandler);
            document.removeEventListener('mousemove', mouseMoveHandler);
            document.removeEventListener('mouseup', mouseUpHandler);
        };
    },
    unmounted(el: HTMLElement) {
        if ((el as any).__draggableCleanup) {
            (el as any).__draggableCleanup();
        }
    }
};

/**
 * 数字千分位格式化指令 v-thousand
 * 用法：<span v-thousand>1234567.89</span>
 */
export const vThousand: Directive = {
    mounted(el: HTMLElement) {
        const formatNumber = (num: string | number) => {
            return Number(num).toLocaleString('en-US');
        };

        const originalText = el.textContent || '';
        el.textContent = formatNumber(originalText);
    }
};

/**
 * 复制文本指令 v-copy
 * 用法：<button v-copy="'要复制的文本'">复制</button>
 */
export const vCopy: Directive<HTMLElement, string> = {
    mounted(el, binding) {
        el.addEventListener('click', () => {
            navigator.clipboard.writeText(binding.value)
                .then(() => {
                    console.log('复制成功');
                })
                .catch(err => {
                    console.error('复制失败', err);
                });
        });
    }
};

/**
 * 点击外部关闭指令 v-click-outside
 * 用法：
 * <div v-click-outside="closeMenu">
 *   <button @click="toggleMenu">菜单</button>
 * </div>
 */
export const vClickOutside: Directive = {
    mounted(el: HTMLElement, binding: DirectiveBinding<(e: Event) => void>) {
        (el as any).__clickOutsideHandler = (event: Event) => {
            if (!el.contains(event.target as Node)) {
                binding.value(event);
            }
        };
        document.addEventListener('click', (el as any).__clickOutsideHandler);
    },
    unmounted(el: HTMLElement) {
        document.removeEventListener('click', (el as any).__clickOutsideHandler);
    }
};

/**
 * 滚动加载指令 v-infinite-scroll
 * 用法：
 * <div v-infinite-scroll="loadMore" threshold="100">
 *   <div v-for="item in list" :key="item.id">{{ item.name }}</div>
 * </div>
 */
export const vInfiniteScroll: Directive = {
    mounted(el: HTMLElement, binding: DirectiveBinding<() => void>) {
        const threshold = binding.arg ? Number(binding.arg) : 100; // 距离底部多少像素时触发

        const handleScroll = () => {
            const { scrollTop, scrollHeight, clientHeight } = el;
            if (scrollTop + clientHeight >= scrollHeight - threshold) {
                binding.value();
            }
        };

        el.addEventListener('scroll', handleScroll);
        (el as any).__infiniteScrollHandler = handleScroll;
    },
    unmounted(el: HTMLElement) {
        el.removeEventListener('scroll', (el as any).__infiniteScrollHandler);
    }
};